#include <iostream>
#include <cstdlib>
#include <ctime>
#include "graph.h"
#include "algorithms.cpp"

#include <string>

#ifdef WIN32
	#include <windows.h>
#endif


using namespace std;

unsigned long long t_ms;

void t_start();
void t_stop();
void t_test();


int main(){

	v_graph v;
	m_graph m;

	char nazwa[70];
	int v1, v2, result;



	
	int wybor;
    
	enum { HELP = 0,
		   L_V = 11, L_M, L_L,
		   P_V = 21, P_M, P_L,
		   DIJ_V = 31, DIJ_M, DIJ_L,
	       BL_V = 41, BL_M, BL_L,
		   KR_V = 51, KR_M, 
		   PR_V = 61, PR_M,
		   Q_T = 71, C_T,
	       QUIT = 9};

	do{
		//cin.ignore(100);
        cin >> wybor;

        switch(wybor){

			default:
				cout << "no such option" << endl;
				break;

            case QUIT:
                break;

            case HELP:
                cout << HELP << " - help" << endl
                     << L_V  << "- load adj_vector" << endl
                     << L_M  << "- load adj_matrix" << endl
					 << L_L  << "- load adj_list" << endl
					 << P_V  << "- print adj_vector" << endl
					 << P_M  << "- print adj_matrix" << endl
					 << P_L  << "- print adj_list" << endl
					 << DIJ_V << "- DIJ_V "<< endl
					 << DIJ_M << "- DIJ_M" << endl
					 << DIJ_L << "- DIJ_L" << endl
					 << BL_V << "- BL_V "<< endl
					 << BL_M << "- BL_M" << endl
					 << BL_L << "- BL_L" << endl
					 << KR_V << "- KR_V "<< endl
					 << KR_M << "- KR_M "<< endl
					 << PR_V << "- PR_V "<< endl
					 << PR_M << "- PR_M "<< endl
					 << Q_T <<" - queue tests" << endl
					 << C_T <<" - clock test" << endl
					 << QUIT << " - quit" << endl;
                break;

	
	
	
            case L_V:
                //cout << ":/";
                cin >> nazwa;
				//g.t_start();
               	v.load(nazwa);
				//g.t_stop();
				//cout << "finished! time:" << g.t_ms << "ms "<< endl;
                break;

			case L_M:
                //cout << ":/";
                cin >> nazwa;
				//g.t_start();
               	m.load(nazwa);
				//g.t_stop();
				//cout << "finished! time:" << g.t_ms << "ms "<< endl;
                break;
/*
			case L_L:
                cout << ":/";
                cin >> nazwa;
				g.t_start();
                g.load_list(nazwa);
				g.t_stop();
				//cout << "finished! time:" << g.t_ms << "ms "<< endl;
                break;*/

			case P_V:
               	traverse(v);
                break;

			case P_M:
                traverse(m);
                break;
/*
            case P_L:
                g.print_list();
                break;*/
				
            case DIJ_V:
                cin >> v1;
                cin >> v2;
				t_start();
                result = dijkstra(v, v1, v2);
				t_stop();
				cout << "DIJ_V;" << nazwa << ";" << v.V() << ";" << v.E() << ";" << result << ";" << t_ms << ";us;" << endl;
                break;

              case DIJ_M:
                cin >> v1;
                cin >> v2;
				t_start();
                result = dijkstra(m, v1, v2);
				t_stop();
				cout << "DIJ_M;" << nazwa << ";" <<  m.V() << ";" << m.E() << ";" << result << ";" << t_ms << ";us;" << endl;
                break;
/*
            case DIJ_L:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.dijkstra_list(v1, v2);
				g.t_stop();
				cout << "DIJ_L;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;
*/
			case BL_V:
                cin >> v1;
                cin >> v2;
				t_start();
                result = bellman_ford(v, v1, v2);
				t_stop();
				cout << "BL_V;" << nazwa << ";" << v.V() << ";" << v.E() << ";" << result << ";" << t_ms << ";us;" << endl;
                break;

			case BL_M:
                cin >> v1;
                cin >> v2;
				t_start();
                result = bellman_ford(m, v1, v2);
				t_stop();
				cout << "BL_M;" << nazwa << ";" << m.V() << ";" << m.E() << ";" << result << ";" << t_ms << ";us;" << endl;
                break;
/*

			case BL_L:
                cin >> v1;
                cin >> v2;
				g.t_start();
                result = g.bellman_ford_list(v1, v2);
				g.t_stop();
				cout << "BL_L;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
                break;

			case KR_V:
				g.t_start();
				result = g.mst_kruskal();
				g.t_stop();
				cout << "KR_V;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

			case KR_M:
				g.t_start();
				result = g.mst_kruskal_matrix();
				g.t_stop();
				cout << "KR_M;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

			case PR_V:
				cin >> v1;
				g.t_start();
				result = g.mst_prim(v1);
				g.t_stop();
				cout << "PR_V;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

			case PR_M:
				cin >> v1;
				g.t_start();
				result = g.mst_prim_matrix(v1);
				g.t_stop();
				cout << "PR_M;" << nazwa << ";" << g.getV() << ";" << g.getE() << ";" << result << ";" << g.t_ms << ";us;" << endl;
				break;

            case Q_T:
				srand((unsigned int) time(NULL));
                g.queue_tests();
                break;


			case C_T:
                g.t_test();
                break;*/
        }

    }while(wybor!=QUIT);


}

void t_start(){
	#ifdef WIN32
		t_ms = GetTickCount();
	#endif

	#ifdef unix
		struct timespec start;
		clock_gettime(CLOCK_REALTIME, &start);
		t_ms = start.tv_sec * 1000000 + start.tv_nsec / 1000;
	#endif

}

void t_stop(){
	#ifdef WIN32
		t_ms = GetTickCount() - t_ms;
	#endif

	#ifdef unix
		struct timespec stop;
		clock_gettime(CLOCK_REALTIME, &stop);
		t_ms = (stop.tv_sec * 1000000 + stop.tv_nsec / 1000) - t_ms;
	#endif
}

void t_test(){
	#ifdef WIN32
		t_start();
		Sleep(1500); //1,5 s
		t_stop();
	#endif
	#ifdef unix
		t_start();
		struct timespec nano = {1,500000000L}; //1,5 s
		nanosleep(&nano, NULL);
		t_stop();
	#endif
	cout << t_ms << " ms" << endl; 
}
